import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';

// 响应数据类型
export interface ApiResponse<T = any> {
  code: number;
  message: string;
  data: T;
  success: boolean;
}

// 请求配置类型
export interface RequestConfig extends AxiosRequestConfig {
  showLoading?: boolean;
  showError?: boolean;
  retryCount?: number;
}

// 错误类型
export interface ApiError {
  code: number;
  message: string;
  details?: any;
}

class HttpClient {
  private instance: AxiosInstance;
  private baseURL: string;
  private timeout: number;

  constructor() {
    // 根据环境设置基础URL
    this.baseURL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8080/api';
    this.timeout = 10000; // 10秒超时

    // 创建axios实例
    this.instance = axios.create({
      baseURL: this.baseURL,
      timeout: this.timeout,
      headers: {
        'Content-Type': 'application/json',
      },
    });

    // 设置拦截器
    this.setupInterceptors();
  }

  // 设置请求和响应拦截器
  private setupInterceptors() {
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // 添加认证token
        const token = this.getToken();
        if (token) {
          config.headers.Authorization = `Bearer ${token}`;
        }

        // 添加请求ID用于追踪
        config.headers['X-Request-ID'] = this.generateRequestId();

        console.log(`🚀 [${config.method?.toUpperCase()}] ${config.url}`, {
          params: config.params,
          data: config.data,
        });

        return config;
      },
      (error) => {
        console.error('❌ Request Error:', error);
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {
        console.log(`✅ [${response.status}] ${response.config.url}`, response.data);
        return response;
      },
      (error: AxiosError) => {
        console.error(`❌ [${error.response?.status}] ${error.config?.url}`, error.response?.data);
        return this.handleError(error);
      }
    );
  }

  // 获取token
  private getToken(): string | null {
    if (typeof window !== 'undefined') {
      return localStorage.getItem('token') || sessionStorage.getItem('token');
    }
    return null;
  }

  // 生成请求ID
  private generateRequestId(): string {
    return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  // 错误处理
  private handleError(error: AxiosError): Promise<never> {
    const apiError: ApiError = {
      code: error.response?.status || 0,
      message: '网络请求失败',
      details: error.response?.data,
    };

    // 根据状态码处理不同错误
    switch (error.response?.status) {
      case 401:
        apiError.message = '未授权，请重新登录';
        this.handleUnauthorized();
        break;
      case 403:
        apiError.message = '权限不足';
        break;
      case 404:
        apiError.message = '请求的资源不存在';
        break;
      case 500:
        apiError.message = '服务器内部错误';
        break;
      case 502:
        apiError.message = '网关错误';
        break;
      case 503:
        apiError.message = '服务不可用';
        break;
      default:
        if (error.code === 'ECONNABORTED') {
          apiError.message = '请求超时';
        } else if (error.message === 'Network Error') {
          apiError.message = '网络连接失败';
        }
    }

    return Promise.reject(apiError);
  }

  // 处理未授权
  private handleUnauthorized() {
    if (typeof window !== 'undefined') {
      localStorage.removeItem('token');
      sessionStorage.removeItem('token');
      // 可以在这里添加跳转到登录页的逻辑
      // window.location.href = '/login';
    }
  }

  // GET请求
  async get<T = any>(url: string, config?: RequestConfig): Promise<T> {
    const response = await this.instance.get<ApiResponse<T>>(url, config);
    return response.data.data;
  }

  // POST请求
  async post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {
    const response = await this.instance.post<ApiResponse<T>>(url, data, config);
    return response.data.data;
  }

  // PUT请求
  async put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {
    const response = await this.instance.put<ApiResponse<T>>(url, data, config);
    return response.data.data;
  }

  // DELETE请求
  async delete<T = any>(url: string, config?: RequestConfig): Promise<T> {
    const response = await this.instance.delete<ApiResponse<T>>(url, config);
    return response.data.data;
  }

  // PATCH请求
  async patch<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {
    const response = await this.instance.patch<ApiResponse<T>>(url, data, config);
    return response.data.data;
  }

  // 上传文件
  async upload<T = any>(url: string, file: File, config?: RequestConfig): Promise<T> {
    const formData = new FormData();
    formData.append('file', file);

    const response = await this.instance.post<ApiResponse<T>>(url, formData, {
      ...config,
      headers: {
        'Content-Type': 'multipart/form-data',
        ...config?.headers,
      },
    });

    return response.data.data;
  }

  // 下载文件
  async download(url: string, filename?: string, config?: RequestConfig): Promise<void> {
    const response = await this.instance.get(url, {
      ...config,
      responseType: 'blob',
    });

    // 创建下载链接
    const blob = new Blob([response.data]);
    const downloadUrl = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = downloadUrl;
    link.download = filename || 'download';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(downloadUrl);
  }

  // 设置token
  setToken(token: string, persistent: boolean = false) {
    if (typeof window !== 'undefined') {
      if (persistent) {
        localStorage.setItem('token', token);
      } else {
        sessionStorage.setItem('token', token);
      }
    }
  }

  // 清除token
  clearToken() {
    if (typeof window !== 'undefined') {
      localStorage.removeItem('token');
      sessionStorage.removeItem('token');
    }
  }

  // 获取原始axios实例（用于特殊需求）
  getInstance(): AxiosInstance {
    return this.instance;
  }
}

// 创建并导出实例
export const http = new HttpClient();

// 导出类型
export type { RequestConfig, ApiResponse, ApiError };
